import json

import os
import uuid

from zeus.operation_service.app.core.asset import ASSET_PATH
from zeus.operation_service.app.core.asset.asset_exception import AssetError
from zeus.operation_service.database import TaskAssetItem
from zeus.operation_service.app.proxy.asset import AssetProxy
from zeus.operation_service.app.core.asset.xml_parse.health_check_xml_parse import ItemParse
from zeus.operation_service.app.core.framework.common.result_code import AssetOperationResultCode
from zeus.operation_service.app.core.framework.common.constant import TaskType
from zeus.operation_service.app.core.file_util import FileUtil
from vulcanus.log.log import LOGGER
from vulcanus.restful.resp.state import (
    SUCCEED,
)


def save_asset(result):
    try:
        asset_items_dir = os.path.join(ASSET_PATH, result['asset_dir'], result['item_dir'])
        support_type = get_support_type(asset_items_dir)
        result['support_type'] = '|'.join(support_type)
        add_ret = AssetProxy().add_asset(result)
        if add_ret != SUCCEED:
            raise AssetError(AssetOperationResultCode.ERR_ASSETS_ADD)
        asset_instance = AssetProxy().get_asset_by_asset_dir(result['asset_dir'])
        save_asset_items(asset_instance, asset_items_dir)
    except AssetError as asset_exception:
        LOGGER.error(asset_exception)
        FileUtil.dir_remove(os.path.join(ASSET_PATH, result['asset_dir']))
        raise asset_exception
    except Exception as e:
        LOGGER.error(e)
        FileUtil.dir_remove(os.path.join(ASSET_PATH, result['asset_dir']))
        raise e


def save_asset_items(asset, asset_items_dir):
    asset_dir_type = {
        "healthcheck": save_health_check_items,
        "datacollection": save_data_collect_items,
        "securitymanage": save_security_manage_items,
    }
    for root, dirs, files in os.walk(asset_items_dir):
        for dir_name in dirs:
            if asset_dir_type.get(dir_name, "null") == "null":
                continue
            dir_path = os.path.join(root, dir_name)
            asset_dir_type.get(dir_name)(asset, dir_path)


def save_health_check_items(asset, task_type_items_dir):
    # 读取巡检目录下的items，并存入数据库
    items_dir = os.path.join(task_type_items_dir, 'Items')
    items_info = list()
    for item_file in os.listdir(items_dir):
        if os.path.isdir(item_file):
            continue
        item_parse = ItemParse(os.path.join(items_dir, item_file))
        item_info = item_parse.get_item_info()
        item_detail = json.dumps(item_info, ensure_ascii=False)
        item_path = item_info["CheckID"]["@value"]
        task_item = TaskAssetItem(item_id=str(uuid.uuid1()), item_path=item_path, item_detail=item_detail,
                                  item_type=TaskType.HEALTH_CHECK, asset_id=asset.asset_id)
        items_info.append(task_item)
    AssetProxy().add_asset_item_batch(items_info)


def save_data_collect_items(asset, task_type_items_dir):
    # 读取采集目录下的items，并存入数据库
    items_dir = os.path.join(task_type_items_dir, 'Items')
    items_info = list()
    for item_file in os.listdir(items_dir):
        if os.path.isdir(item_file):
            continue
        item_parse = ItemParse(os.path.join(items_dir, item_file))
        item_info = item_parse.get_item_info()
        item_detail = json.dumps(item_info, ensure_ascii=False)
        item_path = item_info["ItemID"]["@value"]
        task_item = TaskAssetItem(item_id=str(uuid.uuid1()), item_path=item_path, item_detail=item_detail,
                                  item_type=TaskType.DATA_COLLECT, asset_id=asset.asset_id)
        items_info.append(task_item)
    AssetProxy().add_asset_item_batch(items_info)


def save_security_manage_items(asset, task_type_items_dir):
    # 读取安全目录下的items，并存入数据库
    items_dir = os.path.join(task_type_items_dir, 'Items')
    items_info = list()
    for item_file in os.listdir(items_dir):
        if os.path.isdir(item_file):
            continue
        item_parse = ItemParse(os.path.join(items_dir, item_file))
        item_info = item_parse.get_item_info()
        item_detail = json.dumps(item_info, ensure_ascii=False)
        item_path = item_info["SecurityID"]["@value"]
        task_item = TaskAssetItem(item_id=str(uuid.uuid1()), item_path=item_path, item_detail=item_detail,
                                  item_type=TaskType.SECURITY_MANAGE, asset_id=asset.asset_id)
        items_info.append(task_item)
    AssetProxy().add_asset_item_batch(items_info)


def get_support_type(asset_items_dir):
    support_type_map = {
        "healthcheck": TaskType.HEALTH_CHECK,
        "datacollection": TaskType.DATA_COLLECT,
        "securitymanage": TaskType.SECURITY_MANAGE
    }
    support_type = list()
    for root, dirs, files in os.walk(asset_items_dir):
        for dir_name in dirs:
            if support_type_map.get(dir_name, "null") == "null":
                continue
            support_type.append(support_type_map.get(dir_name))
    return support_type
